package com.ocom.webapi.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.constant.WebApiServiceUrl;
import com.ocom.common.entity.master.EntityCompanyList;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.human.GetUserBypIdsReq;
import com.ocom.common.request.payconfig.GetConsDeviceInfoByAgentRequest;
import com.ocom.common.request.payconfig.GetConsDeviceInfoRequest;
import com.ocom.common.request.payconfig.UpdateConsDeviceInfoRequest;
import com.ocom.common.request.web.ConsumeDeviceAddRequest;
import com.ocom.common.request.web.ConsumeDeviceDeleteRequest;
import com.ocom.common.request.web.ConsumeDeviceInfoRequest;
import com.ocom.common.request.web.ConsumeDeviceModifyRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.utils.poi.ExcelUtil;
import com.ocom.redis.util.RedisUtil;
import com.ocom.security.utils.SecurityUtils;
import com.ocom.webapi.feign.CompanyClientService;
import com.ocom.webapi.feign.HumanClientService;
import com.ocom.webapi.feign.PayConfigClientService;
import com.ocom.webapi.service.ConsumeDeviceService;
import com.ocom.webapi.vo.consumedevice.AddVo;
import com.ocom.webapi.vo.consumedevice.OnShowVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


@RestController
@PreAuthorize("@pms.hasRole('ROLE_WEB')" )
public class ConsumeDeviceController {
	private final Logger log = LoggerFactory.getLogger(ConsumeDeviceController.class);

	@Resource
	RedisUtil redisUtil;

	@Autowired
	PayConfigClientService payConfigClientService;

	@Autowired
	private ConsumeDeviceService consumeDeviceService;

	@Autowired
	CompanyClientService companyClientService;

	@Autowired
	HumanClientService humanClientService;

	//2.4.1消费设备列表（ConsumeDevice/onShow）
	@PostMapping(WebApiServiceUrl.URL_ConsumeDeviceOnShow)
	public Result ConsumeDeviceOnShow(@Valid @RequestBody OnShowVo onShowVo){
		if (onShowVo.getComId() == null){
			log.error("单位编号为空");
			return ResultUtil.error(ResultEnum.Err_203,"单位编号为空");
		}
		if (onShowVo.getPage() == null){
			log.error("页码page为空");
			return ResultUtil.error(ResultEnum.Err_203,"页码page为空");
		}
		if (onShowVo.getSize() == null){
			log.error("页数size为空");
			return ResultUtil.error(ResultEnum.Err_203,"页数size为空");
		}

		return consumeDeviceService.ConsumeDeviceOnShow(onShowVo);
	}

	//2.4.2消费设备信息（ConsumeDevice/info）
	@PostMapping(WebApiServiceUrl.URL_ConsumeDeviceInfo)
	public Result ConsumeDeviceInfo(@Valid @RequestBody ConsumeDeviceInfoRequest request){
		GetConsDeviceInfoRequest getConsDeviceInfoRequest=new GetConsDeviceInfoRequest();
		getConsDeviceInfoRequest.setCom_id(request.getComId());
		getConsDeviceInfoRequest.setDevice_no(request.getDeviceNo());
		getConsDeviceInfoRequest.setPickOne(true);
		return payConfigClientService.getConsDeviceInfo(getConsDeviceInfoRequest);
	}

	//2.4.3消费设备新增（ConsumeDevice/add）
	@PostMapping(WebApiServiceUrl.URL_ConsumeDeviceAdd)
	public Result ConsumeDeviceAdd(@Valid @RequestBody ConsumeDeviceAddRequest request){
		return consumeDeviceService.ConsumeDeviceAdd(request);
	}

	// 消费设备修改（ConsumeDevice/modify）
	@PostMapping(WebApiServiceUrl.URL_ConsumeDeviceModify)
	public Result ConsumeDeviceModify(@Valid @RequestBody ConsumeDeviceModifyRequest request){

		//xf_device_info#comId:526#machNo:21105432#
		redisUtil.del("xf_device_info#comId:"+request.getComId()+"#machNo:"+request.getDeviceNo()+"#");

		UpdateConsDeviceInfoRequest updateConsDeviceInfoRequest=new UpdateConsDeviceInfoRequest();
		updateConsDeviceInfoRequest.setCom_id(request.getComId());
		updateConsDeviceInfoRequest.setDevice_no(request.getDeviceNo());
		updateConsDeviceInfoRequest.setDevice_name(request.getDeviceName());
		updateConsDeviceInfoRequest.setDevice_type(request.getDeviceType());
		updateConsDeviceInfoRequest.setDevice_mode(request.getDeviceMode());
		updateConsDeviceInfoRequest.setDevice_ver_type(request.getDeviceVerType());
		updateConsDeviceInfoRequest.setApp_ver(request.getAppVer());
		updateConsDeviceInfoRequest.setAiotNo(request.getAiotNo());
		updateConsDeviceInfoRequest.setPoint_id(request.getPointId());
		updateConsDeviceInfoRequest.setConsType(request.getConsType());
		updateConsDeviceInfoRequest.setFaceAuth(request.getFaceAuth());
		updateConsDeviceInfoRequest.setFaceAuthTime(request.getFaceAuthTime());
		updateConsDeviceInfoRequest.setFaceAuthType(request.getFaceAuthType());
		return payConfigClientService.updateConsDeviceInfo(updateConsDeviceInfoRequest);
	}

	//2.4.6消费设备删除（ConsumeDevice/delete）
	@PostMapping(WebApiServiceUrl.URL_ConsumeDeviceDelete)
	public Result ConsumeDeviceDelete(@Valid @RequestBody ConsumeDeviceDeleteRequest request){
		redisUtil.del("xf_device_info#comId:"+request.getComId()+"#machNo:"+request.getDeviceNo()+"#");
		return consumeDeviceService.ConsumeDeviceDelete(request);
	}


	/**
	 * 导入机器模板（ConsumeDevice/importDeviceTemplate）
	 * */
	@GetMapping(WebApiServiceUrl.URL_ConsumeDeviceImportDeviceTemplate)
	public void ImportDeviceTemplate(HttpServletResponse response) throws IOException {
		ExcelUtil<AddVo> util = new ExcelUtil<AddVo>(AddVo.class);
		util.importTemplateExcel(response, "设备数据");
	}

	// 导入消费设备（ConsumeDevice/import）
	@PostMapping(WebApiServiceUrl.URL_ConsumeDeviceImport)
	public Result ConsumeDeviceImport(Long comId,@RequestPart("file") MultipartFile file){
		return consumeDeviceService.ConsumeDeviceImport(comId,file);
	}


	//3.4.11重置设备白名单（ConsumeDevice/resetList）
	@PostMapping(WebApiServiceUrl.URL_ConsumeDeviceResetList)
	public Result ConsumeDeviceResetList(@RequestBody JSONObject jsonObject){
		log.info("重置设备白名单 ConsumeDevice/resetList 【{}】【{}】",SecurityUtils.getYoCiUser(),jsonObject);
		return payConfigClientService.resendWhiteList(jsonObject);
	}

	//3.4.12重置设备参数（ConsumeDevice/resetMach）
	@PostMapping(WebApiServiceUrl.URL_ConsumeDeviceResetMach)
	public Result consumeDeviceResetMach(@RequestBody JSONObject jsonObject){

		return payConfigClientService.resetMach(jsonObject);
	}

	//3.4.13设备上传人脸数据（ConsumeDevice/uploadErrFace）
	@PostMapping(WebApiServiceUrl.URL_ConsumeDeviceUploadErrFace)
	public Result consumeDeviceUploadErrFace(@RequestBody JSONObject jsonObject){
		String machNos = jsonObject.getString("machNo");
		String[]  machs = machNos.split(",");
		if(machs.length<=0){
			return ResultUtil.error(ResultEnum.Err_2005);
		}
		for (String mach : machs){
			redisUtil.set("faceFalg:"+mach,1,86400l);
		}
		return ResultUtil.success();
	}



	// 3.4.16代理商消费设备列表（DeleteConsumeDevice/onShow）
	@PostMapping(WebApiServiceUrl.Url_DeleteConsumeDeviceOnShow)
	public Result DeleteConsumeDeviceOnShow(@RequestBody GetConsDeviceInfoByAgentRequest request){
		List<Long> comIds= new ArrayList<>();
		if(request.getAgentId()==null || request.getAgentId()==0l){
			request.setAgentId(SecurityUtils.getYoCiUser().getComId());
		}
		if(request.getComId()==null) {
			Result result = companyClientService.getCompanyListByAgentId(request.getAgentId());
			if (result.getCode() != 200 || result.getData() == null) {
				return result;
			}
			List<EntityCompanyList> list = JSON.parseArray(JSON.toJSONString(result.getData()), EntityCompanyList.class);
			if(list==null || list.size()==0)  return ResultUtil.error(ResultEnum.Err_1001);
			comIds= list.stream().map(EntityCompanyList -> EntityCompanyList.getComId()).collect(Collectors.toList());
		}else{
			comIds.add(request.getComId());
		}
		request.setComIds(comIds);
		return payConfigClientService.getConsDeviceInfoByAgent(request);
	}

	/**
	 *@Description:生成设备收款码
	 * @author lu 
	 * @param jsonObject
	 * @return com.ocom.common.resp.Result
	 * @date 2023/3/10 10:36       
	 */
	@PostMapping(WebApiServiceUrl.Url_ConsumeDeviceGetMachPayCode)
	public Result gonsumeDeviceGetMachPayCode(@RequestBody JSONObject jsonObject){
		return payConfigClientService.getConsDevicePayCode(jsonObject.getLong("companyId"),jsonObject.getString("machNo"));
	}

	/**
	 * 生成账号付款码
	 * @param jsonObject
	 * @return
	 */
	@PostMapping(WebApiServiceUrl.Url_ConsumeDeviceGetAccountPayCode)
	public Result consumeDeviceGetAccountPayCode(@RequestBody JSONObject jsonObject){
		return payConfigClientService.getConsAccountPayCode(jsonObject.getLong("companyId"),jsonObject.getString("machNo"));
	}


	/**
	 *@Description:删除设备收款码
	 * @author lu 
	 * @param jsonObject
	 * @return com.ocom.common.resp.Result
	 * @date 2023/3/10 13:22       
	 */
	@PostMapping(WebApiServiceUrl.Url_ConsumeDevicedeleteMachPayCode)
	public Result consumeDevicedeleteMachPayCode(@RequestBody JSONObject jsonObject){
		return payConfigClientService.removeConsDevicePayCode(jsonObject.getLong("companyId"),jsonObject.getString("machNo"));
	}

	@PostMapping(WebApiServiceUrl.Url_ConsumeDeviceDeleteAccountPayCode)
	public Result consumeDevicedeleteAccountPayCode(@RequestBody JSONObject jsonObject){
		return payConfigClientService.removeConsAccountPayCode(jsonObject.getLong("companyId"),jsonObject.getString("machNo"));
	}


	@PostMapping(WebApiServiceUrl.Url_consumeDeviceErrFaceList)
	public Result consumeDeviceErrFaceList(@RequestBody JSONObject jsonObject) {

		Map<String, Long> resMap = new HashMap<>();

		// 获取当前时间
		Date currentDate = new Date();
		//	System.out.println("当前时间: " + currentDate);

		String date = DateUtils.getStrDate(currentDate, "yyyyMMddHH");

		String faceErrKey = "FaceErr:" + SecurityUtils.getYoCiUser().getComId() + ":" + jsonObject.getString("deviceNo") + ":" + date;

		resMap.put(date, redisUtil.hmLen(faceErrKey));

		for (int i = 0; i < 24; i++) {
			// 获取当前时间的毫秒数
			long currentTimeMillis = currentDate.getTime();

			// 计算一小时的毫秒数 (1小时 * 60分钟 * 60秒 * 1000毫秒)
			long oneHourInMillis = i * 60 * 60 * 1000;

			// 减去一小时
			Date oneHourAgo = new Date(currentTimeMillis - oneHourInMillis);
			System.out.println("一小时前: " + oneHourAgo);

			date = DateUtils.getStrDate(oneHourAgo, "yyyyMMddHH");

			faceErrKey = "FaceErr:" + SecurityUtils.getYoCiUser().getComId() + ":" + jsonObject.getString("deviceNo") + ":" + date;

			resMap.put(date, redisUtil.hmLen(faceErrKey));

		}
//
//		// 获取当前时间的毫秒数
//		long currentTimeMillis = currentDate.getTime();
//
//		// 计算一小时的毫秒数 (1小时 * 60分钟 * 60秒 * 1000毫秒)
//		long oneHourInMillis = 60 * 60 * 1000;
//
//		// 减去一小时
//		Date oneHourAgo = new Date(currentTimeMillis - oneHourInMillis);
//		System.out.println("一小时前: " + oneHourAgo);

		return ResultUtil.success(resMap);
	}


	@PostMapping(WebApiServiceUrl.Url_consumeDeviceErrFaceUser)
	public Result consumeDeviceErrFaceUser(@RequestBody JSONObject jsonObject) {
		String faceErrKey = "FaceErr:" + SecurityUtils.getYoCiUser().getComId() + ":" + jsonObject.getString("deviceNo") + ":" + jsonObject.getString("date");
		List<Map.Entry<String, String>> entryList = redisUtil.hmScan(faceErrKey);

		List<Long> pids =new ArrayList<>();
		if(entryList.size()>0){
			for (Map.Entry<String, String> entry:entryList){
				pids.add(Long.valueOf(entry.getKey()));
			}
			GetUserBypIdsReq getUserBypIdsReq=new GetUserBypIdsReq();
			getUserBypIdsReq.setComId(SecurityUtils.getYoCiUser().getComId());
			getUserBypIdsReq.setPIds(pids);
			return humanClientService.getUserBypIds(getUserBypIdsReq);

		}
		return ResultUtil.success(pids);
	}


	@PostMapping(WebApiServiceUrl.Url_delConsumeDeviceErrFaceKey)
	public Result delConsumeDeviceErrFaceKey(@RequestBody JSONObject jsonObject) {
		String faceErrKey = "FaceErr:" + SecurityUtils.getYoCiUser().getComId() + ":" + jsonObject.getString("deviceNo") + ":" + jsonObject.getString("date");
		redisUtil.del(faceErrKey);
		return ResultUtil.success();
	}











}